#include <condition_variable>
#include <mutex>
#include <signal.h>
#include "BaseCmdParam.h"
#include <simplemq/simplemq_mqtt.hpp>
#include "person.hpp"
/************************************************************************/
/* MQTT 订阅测试                                                        */
/************************************************************************/
using namespace simplemq;
// 命令行参数解析器
class ClientConfig : public gdface::BaseClientConfig {
public:
	const std::string PARAM_CHANNEL_NAME = "channel";
	const std::string PARAM_USERNAME = "username";
	const std::string PARAM_PASSWORD = "password";
	/** 频道名，默认'c1' */
	std::string channel;
	std::string username;
	std::string password;
	ClientConfig():gdface::BaseClientConfig(MQTT_DEFAULT_PORT),channel(),password() {
		cmdparam.add<std::string>(PARAM_CHANNEL_NAME, 'c', "channel name for subscribing", false, "c1");
		cmdparam.add<std::string>(PARAM_USERNAME, 'u', "username for authorization", false, "");
		cmdparam.add<std::string>(PARAM_PASSWORD, 'a', "password for authorization", false, "");
	}
	~ClientConfig() = default;
	void afterParse() {
		gdface::BaseClientConfig::afterParse();
		channel = cmdparam.get<std::string>(PARAM_CHANNEL_NAME);
		username = cmdparam.get<std::string>(PARAM_USERNAME);
		password = cmdparam.get<std::string>(PARAM_PASSWORD);
	}
};

std::condition_variable should_exit;

void
sigint_handler(int) {
	should_exit.notify_all();
}

ClientManager cmgr;

std::shared_ptr<simplemq::MqttSubscriber> sub;

int
main(int argc, char *argv[]) {
	ClientConfig param;
	param.parse(argc, argv);
	try
	{
		auto sub = cmgr.getSubscriber(mq_client_params{ param.host, param.port, param.password,param.username });
#if 0
		Channel ch(param.channel, [](const std::string &msg) {
			// 从频道收到消息直接当作字符串输出
			std::cout << "MESSAGE " << msg << std::endl;
		});
		sub->_register({ ch });
#else
		// 定义频道对象
		Channel ch(param.channel, /** 消息处理函数(lamda表达式) */[](const simplemq::json &j) {
			// 从频道收到消息反序列化成person对象
			try {
				//auto p = j.get<person>();
				//std::cout << "RECEIVED person:" << p << std::endl;
				std::cout << "RECEIVED JSON:" << j.dump() << std::endl;
			}
			catch (/** 可能抛出的json解析异常 */simplemq::json::parse_error & e) {
				SAMPLE_LOG("ERROR {}: {}", typeid(e).name(), e.what());
			}
			catch (/** 可能抛出的其他json异常 */simplemq::json::exception & e) {
				SAMPLE_LOG("ERROR {}: {}", typeid(e).name(), e.what());
			}
		});
		// 注册/订阅消息频道
		sub->_register({ ch });
#endif
	}
	catch (const std::exception &e)
	{
		SAMPLE_ERR("{}:{}", typeid(e).name(), e.what());
	}
	catch (...)
	{
		SAMPLE_ERR("unknow error");
	}
	signal(SIGINT, &sigint_handler);
	std::mutex mtx;
	std::unique_lock<std::mutex> lock(mtx);
	should_exit.wait(lock);
	return 0;
}

